// Swap the first entry with the entry found in the collision chain
// to speed up next hardware search (and keep LRU).
// In comments 1 stands for the first entry and 2 for the found entry.
- ld8 r25 = [r17] // Read value of 2
- ld8 r27 = [r18] // Read value of 1
ld8 r29 = [r28] // Read tag of 1
dep r22 = -1,r24,63,1 // set ti=1 of 2 (to disable it during the swap)
;;
+ ld8 r25 = [r17] // Read value of 2
+ ld8 r27 = [r18] // Read value of 1
st8 [r16] = r29, VLE_ITIR_OFFSET - VLE_TITAG_OFFSET // Write tag of 2
st8 [r28] = r22, VLE_ITIR_OFFSET - VLE_TITAG_OFFSET // Write tag of 1
- extr.u r19 = r27, 56, 4 // Extract collision chain length
mf
;;
ld8 r29 = [r16] // read itir of 2
ld8 r22 = [r28] // read itir of 1
- dep r27 = r0, r27, 56, 4 // Clear collision chain length for 2
- dep r25 = r19, r25, 56, 4 // Write collision chain length for 1
+ st8 [r18] = r25 // Write value of 1
+ st8 [r17] = r27 // Write value of 2
;;
st8 [r16] = r22 // Write itir of 2
st8 [r28] = r29, VLE_TITAG_OFFSET - VLE_ITIR_OFFSET // write itir of 1
- st8 [r18] = r25 // Write value of 1
- st8 [r17] = r27 // Write value of 2
;;
st8.rel [r28] = r24 // Write tag of 1 (with ti=0)
// Insert the translation entry
(p7)mov r17 = r23;
(p7)br.sptk vmx_dtlb_loop
;;
- ld8 r25 = [r17]
- ld8 r27 = [r18]
ld8 r29 = [r28]
dep r22 = -1,r24,63,1 //set ti=1
;;
+ ld8 r25 = [r17]
+ ld8 r27 = [r18]
st8 [r16] = r29, VLE_ITIR_OFFSET - VLE_TITAG_OFFSET
st8 [r28] = r22, VLE_ITIR_OFFSET - VLE_TITAG_OFFSET
- extr.u r19 = r27, 56, 4
mf
;;
ld8 r29 = [r16]
ld8 r22 = [r28]
- dep r27 = r0, r27, 56, 4
- dep r25 = r19, r25, 56, 4
+ st8 [r18] = r25
+ st8 [r17] = r27
;;
st8 [r16] = r22
st8 [r28] = r29, VLE_TITAG_OFFSET - VLE_ITIR_OFFSET
- st8 [r18] = r25
- st8 [r17] = r27
;;
st8.rel [r28] = r24
itc.d r25
return NULL;
}
-static void thash_recycle_cch(thash_cb_t *hcb, thash_data_t *hash)
+static void thash_recycle_cch(thash_cb_t *hcb, thash_data_t *hash,
+ thash_data_t *tail)
{
- thash_data_t *p, *q;
- int i = 0;
-
- p = hash;
- for (i = 0; i < MAX_CCN_DEPTH; i++) {
- p = p->next;
- }
- q = hash->next;
- hash->len = 0;
+ thash_data_t *head = hash->next;
+
hash->next = 0;
- p->next = hcb->cch_freelist;
- hcb->cch_freelist = q;
+ tail->next = hcb->cch_freelist;
+ hcb->cch_freelist = head;
}
static void vmx_vhpt_insert(thash_cb_t *hcb, u64 pte, u64 itir, u64 ifa)
{
- u64 tag;
+ u64 tag, len;
ia64_rr rr;
thash_data_t *head, *cch;
head = (thash_data_t *)ia64_thash(ifa);
tag = ia64_ttag(ifa);
- /* Find a free (ie invalid) entry. */
- cch = head;
- while (cch) {
- if (INVALID_VHPT(cch))
- break;
- cch = cch->next;
- }
- if (cch) {
+ if (!INVALID_VHPT(head)) {
+ /* Find a free (ie invalid) entry. */
+ len = 0;
+ cch = head;
+ do {
+ ++len;
+ if (cch->next == NULL) {
+ if (len >= MAX_CCN_DEPTH) {
+ thash_recycle_cch(hcb, head, cch);
+ cch = cch_alloc(hcb);
+ } else {
+ cch = __alloc_chain(hcb);
+ }
+ cch->next = head->next;
+ head->next = cch;
+ break;
+ }
+ cch = cch->next;
+ } while (!INVALID_VHPT(cch));
+
/* As we insert in head, copy head. */
- if (cch != head) {
- local_irq_disable();
- cch->page_flags = head->page_flags;
- cch->itir = head->itir;
- cch->etag = head->etag;
- head->ti = 1;
- local_irq_enable();
- }
- } else {
- if (head->len >= MAX_CCN_DEPTH) {
- thash_recycle_cch(hcb, head);
- cch = cch_alloc(hcb);
- } else {
- cch = __alloc_chain(hcb);
- }
local_irq_disable();
- *cch = *head;
+ cch->page_flags = head->page_flags;
+ cch->itir = head->itir;
+ cch->etag = head->etag;
head->ti = 1;
- head->next = cch;
- head->len = cch->len + 1;
- cch->len = 0;
local_irq_enable();
}
- //here head is invalid
+ /* here head is invalid. */
wmb();
head->page_flags=pte;
head->itir = rr.ps << 2;
hash->itir = head->itir;
head->itir = itir;
- head->len = hash->len;
- hash->len = 0;
return head;
}
return hash;
head = hcb->hash;
num = (hcb->hash_sz/sizeof(thash_data_t));
do {
- head->len = 0;
head->next = 0;
head++;
num--;
*/
static void vtlb_insert(VCPU *v, u64 pte, u64 itir, u64 va)
{
- thash_data_t *hash_table, *cch;
+ thash_data_t *hash_table, *cch, *tail;
/* int flag; */
ia64_rr vrr;
/* u64 gppn, ppns, ppne; */
vrr.ps = itir_ps(itir);
VMX(v, psbits[va >> 61]) |= (1UL << vrr.ps);
hash_table = vtlb_thash(hcb->pta, va, vrr.rrval, &tag);
+ len = 0;
cch = hash_table;
- while (cch) {
+ do {
if (INVALID_TLB(cch)) {
- len = cch->len;
cch->page_flags = pte;
- cch->len = len;
cch->itir = itir;
cch->etag = tag;
return;
}
+ ++len;
+ tail = cch;
cch = cch->next;
- }
- if (hash_table->len >= MAX_CCN_DEPTH) {
- thash_recycle_cch(hcb, hash_table);
+ } while(cch);
+ if (len >= MAX_CCN_DEPTH) {
+ thash_recycle_cch(hcb, hash_table, tail);
cch = cch_alloc(hcb);
}
else {
cch->next = hash_table->next;
wmb();
hash_table->next = cch;
- hash_table->len += 1;
return;
}